using System;
using System.ComponentModel;
using System.Collections.Generic;
using System.Xml.Serialization;

using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics;

namespace PartBuilder
{
	/// <summary>
	/// Editable form of Part
	/// </summary>
	public class EditablePart
	{
		public Matrix Translation = Matrix.Identity;

		Vector2 position;
		float rotation;


		public List<Shape> Shapes = new List<Shape>();

		#region Properties
		public Vector2 Position
		{
			get { return position; }
			set
			{
				position = value;
				Translation.M41 = position.X;
				Translation.M42 = position.Y;
			}
		}

		public float Rotation
		{
			get { return rotation; }
			set
			{
				rotation = value;
				//Rotation along the Z axis
				float cos = (float)Math.Cos(rotation);
				float sin = (float)Math.Sin(rotation);
				Translation.M11 = cos;
				Translation.M12 = sin;
				Translation.M21 = -sin;
				Translation.M22 = cos;
			}
		}

		#endregion

		public class Shape
		{
			internal System.Drawing.Color ShapeColor = System.Drawing.Color.White;


			List<Edge> edges = new List<Edge>(3);
			public List<Edge> Edges { get { return edges; } }

			int edgeCount = 3;
			public int EdgeCount
			{
				get { return edgeCount; }
				set
				{
					if (edgeCount == value)
						return;

					edgeCount = value;
					Resize();
				}
			}

			void Resize()
			{

				Array.Resize<bool>(ref hiddenEdges, edgeCount);

				while (edges.Count != edgeCount)
					if (edgeCount > edges.Count) edges.Add(new Edge());
					else edges.RemoveAt(edges.Count - 1);

				float angle = MathHelper.TwoPi / edgeCount;
				float start = (float)Math.Atan2(edges[0].LengthSinCos.Y, edges[0].LengthSinCos.Z);

				for (int ii = 1; ii < edgeCount; ++ii)
				{
					edges[ii].Point.X = edges[ii - 1].Point.X + edges[ii - 1].LengthSinCos.X * edges[ii - 1].LengthSinCos.Z;
					edges[ii].Point.Y = edges[ii - 1].Point.Y + edges[ii - 1].LengthSinCos.X * edges[ii - 1].LengthSinCos.Y;
					edges[ii].LengthSinCos.X = edges[ii - 1].LengthSinCos.X;
					edges[ii].LengthSinCos.Y = (float)Math.Sin(start + ii * angle);
					edges[ii].LengthSinCos.Z = (float)Math.Cos(start + ii * angle);
				}

			}

			public Shape()
			{
				edges.Add(new Edge());
				edges[0].LengthSinCos = new Vector3(35, (float)Math.Sin(0), (float)Math.Cos(0));
				edges[0].Point.X = -edges[0].LengthSinCos.X / 2;

				Resize();
			}

			public Shape(Edge edge)
			{
				edges.Add(new Edge());
				edges[0].Point.X = edge.Point.X + edge.LengthSinCos.X * edge.LengthSinCos.Z;
				edges[0].Point.Y = edge.Point.Y + edge.LengthSinCos.X * edge.LengthSinCos.Y;

				edges[0].LengthSinCos.X = edge.LengthSinCos.X;
				edges[0].LengthSinCos.Y = -edge.LengthSinCos.Y;
				edges[0].LengthSinCos.Z = -edge.LengthSinCos.Z;

				Resize();

			}

			bool[] hiddenEdges = new bool[] { };
			public bool[] HiddenEdges { get { return hiddenEdges; } }


			public class Edge
			{
				internal Vector2 Point = Vector2.Zero;
				internal Vector3 LengthSinCos;
				internal Color color = Color.White;

				public System.Drawing.Color EdgeColor
				{
					get
					{
						return System.Drawing.Color.FromArgb((int)color.PackedValue);
					}
					set { color.PackedValue = (uint)value.ToArgb(); }
				}

				internal bool mountPoint = false;

				public Vector2 Position { get { return Point; } set { } }

				public override string ToString()
				{
					return String.Format("{{{0}}}", Point);
				}
			}
		}
	}
}
